// deno run --allow-read --allow-write --allow-net scripts/generate-lts.ts
//

import { gt } from "https://deno.land/std@0.192.0/semver/gt.ts";
import { parse } from "https://deno.land/std@0.192.0/semver/parse.ts";

interface NodeReleaseMetadata {
  version: string;
  date: string;
  files: string[];
  npm?: string;
  v8: string;
  uv?: string;
  zlib?: string;
  openssl?: string;
  modules?: string;
  lts: string | boolean;
  security: boolean;
}

type Tsconfig = Record<string, any>;

const versionRegex = /v(\d+)\.(\d+)\.(\d+)/;

const releasesResponse = await fetch("https://nodejs.org/download/release/index.json");
const releasesJson = (await releasesResponse.json()) as NodeReleaseMetadata[];
const lts = releasesJson
  .filter((r) => r.lts)
  .reduce(
    (prevValue, currValue) => (gt(parse(currValue.version), parse(prevValue.version)) ? currValue : prevValue),
    {
      version: "v0.0.0"
    }
  );
const baseMajorVersion = (lts.version.match(versionRegex) || [])[1];
const base = `node${baseMajorVersion}`;
const versioned = {
  $schema: "https://www.schemastore.org/tsconfig",
  display: `Node LTS (${baseMajorVersion})`,
  _version: lts.version.substring(lts.version.indexOf("v") + 1)
};

import * as path from "https://deno.land/std/path/mod.ts";
import stripJsonComments from "https://esm.sh/strip-json-comments";
import { deepMerge } from "https://deno.land/std/collections/deep_merge.ts";

const packageText = await Deno.readTextFile(path.join(Deno.cwd(), "bases", `${base}.json`));

const parsed = JSON.parse(stripJsonComments(packageText)) as Tsconfig;

// This is to get the _version property to show up directly under the display property
const parsedAndOrdered = deepMerge(versioned, parsed);
parsedAndOrdered.display = versioned.display;

const serializedConfig =
  "// This file was autogenerated by a script\n" +
  `// Equivalent to a config of: ${base}\n` +
  JSON.stringify(parsedAndOrdered, null, "  ") +
  "\n";

const filePath = path.join(Deno.cwd(), "bases/node-lts.json");
Deno.writeTextFile(filePath, serializedConfig);
